import { HasOwner } from "xbsj-base";
import { PSUEViewer } from "./PSUEViewer";
import { RECEIVE, SEND } from "./dataFormats";
export class ESMsgWebSocketWrapper extends HasOwner<PSUEViewer> {
    get esUeViewer() { return this.owner; }

    // private _responseEvent = this.disposeVar(new XEvent<[string]>());
    // get responseEvent() { return this._responseEvent; }
    private _processResponseFn = (e: string) => this.esUeViewer.processResponse(e);

    get uri() { return this._uri; }


    private _inner = new WebSocket(this._uri);
    private _innerInit = (() => {
        this.inner.onmessage = (messageEvent) => {
            if (this.isDestroyed())
                return;
            //修改为处理 ue返回的消息，msg是字符串
            //console.log(msg.data);
            let fileReader = new FileReader();
            fileReader.onload = event => {
                if (this.isDestroyed())
                    return;
                // @ts-ignore
                let arrayBuffer = event.target.result as ArrayBuffer;

                //先解析出来
                // @ts-ignore
                let uint32View = new Uint32Array(arrayBuffer);

                let byteOffset = 0;
                if (uint32View[0] === RECEIVE.Response) {
                    byteOffset += 4;
                    //解析消息个数
                    let msgCount = uint32View[byteOffset / 4];
                    byteOffset += 4;

                    for (let i = 0; i < msgCount; i++) {
                        let msgSize = uint32View[byteOffset / 4];
                        byteOffset += 4;
                        let response = new TextDecoder('utf-8').decode(arrayBuffer.slice(byteOffset, byteOffset + msgSize));
                        //每个response是个json
                        // console.log(response);
                        byteOffset += msgSize;

                        // @ts-ignore
                        // TODO
                        // that.processResponse(response)
                        // this.responseEvent.emit(response);
                        this._processResponseFn(response);
                    }
                }
            };
            fileReader.readAsArrayBuffer(messageEvent.data);
        }

        this.inner.onopen = () => {
            if (this.isDestroyed()) return;
            console.warn("earthsdk message websocket server connected:", this.uri);
            console.log("%c[EarthSDK websocket open]", "background: #a6ec99; color: black", `open`);

            this.owner.dispatchEvent(new CustomEvent('esmsgwsopen', { detail: 'websocket open' }));
        }

        this._inner.onclose = (e) => {
            if (this.isDestroyed()) return;
            console.log("%c[EarthSDK websocket close ]", "background: red; color: black", `error`);
            this.owner.dispatchEvent(new CustomEvent('error', { detail: 'websocket close' }));
        }

        this._inner.onerror = (e) => {
            if (this.isDestroyed()) return;
            console.log("%c[EarthSDK websocket error ]", "background: red; color: black", `error`);
            this.owner.dispatchEvent(new CustomEvent('error', { detail: 'websocket error' }));
        }

        this.d(() => { (!this.isDestroyed()) && this._inner.close(); });

    })();
    get inner() { return this._inner; }

    constructor(owner: PSUEViewer, private _uri: string) {
        super(owner);
        //this.dispose(this.responseEvent.disposableOn(e => this.esUeViewer.processResponse(e)));
    }

    sendInputData(data: ArrayBuffer) {
        const esMsgWs = this.inner;
        if (esMsgWs.readyState !== WebSocket.OPEN) return;

        const srcBuf = new Uint8Array(data);
        // 判断事件类型，我们只截获鼠标键盘事件，以及ui事件，其他不处理
        const msgType = srcBuf[0];
        if (msgType >= SEND.UIInteraction && msgType <= SEND.MouseWheel) {
            const data2 = new ArrayBuffer(data.byteLength + 4);
            new DataView(data2).setUint32(0, data.byteLength, true);
            new Uint8Array(data2, 4).set(new Uint8Array(data));
            esMsgWs.send(new DataView(data2));
            return true;
        } else {
            return false;
        }
    }

    // 发送通用消息
    emitDescriptorWithString(messageType: number, descriptorAsString: string) {
        // Convert the dscriptor object into a JSON string.
        let utf8Array = new TextEncoder().encode(descriptorAsString);
        // Add the UTF-8 JSON string to the array byte buffer, going two bytes at
        // a time. 
        let data = new DataView(new ArrayBuffer(1 + 2 + utf8Array.length));
        let byteIdx = 0;
        data.setUint8(byteIdx, messageType);
        byteIdx++;
        data.setUint16(byteIdx, utf8Array.length, true);
        byteIdx += 2;

        for (let i = 0; i < utf8Array.length; i++) {
            data.setUint8(byteIdx, utf8Array[i]);
            byteIdx += 1;
        }
        try {
            this.sendInputData(data.buffer);
        } catch (error) {
            console.error(`data.buffer.size: ${data.buffer.byteLength} 独立通道 sendInputData error: ${error}`, error);
        }
    }

    destroyImpl() {
        if (this._inner) {
            this._inner.close();
        }
    }
}
